/*
 * Copyright (c) 2013 哈尔滨亿时代数码科技开发有限公司（www.hrbesd.com）. All rights reserved.
 * 
 * HRBESD PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.esd.crm.controller;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.esd.crm.Constants;
import com.esd.crm.UsernameAndPasswordMd5;
import com.esd.crm.entity.User;
import com.esd.crm.service.UserService;

/**
 * 管理员
 * 
 * @author snailzhang
 * 
 */
@Controller
@RequestMapping("/security")
public class ManagerController {
	private static final Logger logger = LogManager.getLogger(ManagerController.class);
	@Autowired
	private UserService userService;

	/**
	 * 用户不能为空
	 */
	@Value("${MSG_USER_NOT_EMPTY}")
	private String MSG_USER_NOT_EMPTY;

	/**
	 * 密码不能为空
	 */
	@Value("${MSG_PASSWORD_NOT_EMPTY}")
	private String MSG_PASSWORD_NOT_EMPTY;
	/**
	 * 用户已存在
	 */
	@Value("${MSG_USER_EXIST}")
	private String MSG_USER_EXIST;

	/**
	 * 更新成功
	 */
	@Value("${MSG_UPDATE_SUCCESS}")
	private String MSG_UPDATE_SUCCESS;
	/**
	 * 用户名可用
	 */
	@Value("${MSG_USERNAME_DO}")
	private String MSG_USERNAME_DO;

	/**
	 * 修改失败
	 */
	@Value("${MSG_UPDATE_ERROR}")
	private String MSG_UPDATE_ERROR;

	// 数据库配置获取

	@Value("${spring.datasource.driver-class-name}")
	private String SPRING_DATASOURCE_DRIVER;
	@Value("${spring.datasource.url}")
	private String SPRING_DATASOURCE_URL;
	@Value("${spring.datasource.username}")
	private String SPRING_DATASOURCE_USERNAME;
	@Value("${spring.datasource.password}")
	private String SPRING_DATASOURCE_PASSWORD;

	@RequestMapping(value = "/sdu", method = RequestMethod.GET)
	@ResponseBody
	public Map<String, Object> getSDU() {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("sdu", SPRING_DATASOURCE_URL);
		return map;
	}

	/**
	 * 登录管理员页
	 * 
	 * @param loginrName
	 * @return
	 */
	@RequestMapping(value = "/dbs", method = RequestMethod.GET)
	public ModelAndView dbsGet() {
		return new ModelAndView("dbs/dbs");
	}

	/**
	 * 登录管理员页
	 * 
	 * @param loginrName
	 * @return
	 */
	@RequestMapping(value = "/getDatabases", method = RequestMethod.GET)
	@ResponseBody
	public Map<String, Object> getDatabases(HttpServletRequest request) {
		Map<String, Object> map = new HashMap<String, Object>();
		List<String> list = new ArrayList<String>();
		// 创建数据库，先删除数据库重新创建完成
		Connection conn = null;
		Statement stat = null;
		try {
			Class.forName(SPRING_DATASOURCE_DRIVER);
			// 一开始必须填一个已经存在的数据库
			conn = DriverManager.getConnection(SPRING_DATASOURCE_URL, SPRING_DATASOURCE_USERNAME, SPRING_DATASOURCE_PASSWORD);
			stat = conn.createStatement();
			// 创建数据库hello
			stat.executeQuery("show databases");
			ResultSet rs = stat.getResultSet();
			while (rs.next()) {
				String s = rs.getString(1);
				if (s.startsWith("crm")) {
					if (s.equals("crm") == false) {
						list.add(s);
					}
				}
			}
			map.put("list", list);
			stat.close();
			conn.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (stat != null) {
				try {
					stat.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return map;

	}
	
	/**
	 * 截断制定表
	 * 
	 * @param loginrName
	 * @return
	 */
	@RequestMapping(value = "/clearTable", method = RequestMethod.GET)
	@ResponseBody
	public Map<String, Object> clearTable(HttpServletRequest request) {
		Map<String, Object> map = new HashMap<String, Object>();
		String t = request.getParameter("t");
		// 创建数据库，先删除数据库重新创建完成
		Connection conn = null;
		Statement stat = null;
		Boolean bo=true;
		try {
			Class.forName(SPRING_DATASOURCE_DRIVER);
			// 一开始必须填一个已经存在的数据库
			conn = DriverManager.getConnection(SPRING_DATASOURCE_URL, SPRING_DATASOURCE_USERNAME, SPRING_DATASOURCE_PASSWORD);
			stat = conn.createStatement();
			// 创建数据库hello
			String trun="truncate table "+t;
			bo=stat.execute(trun);
			stat.close();
			conn.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (stat != null) {
				try {
					stat.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		map.put("truncate", bo);
		return map;

	}
	

	/**
	 * 导出当年账套
	 * 
	 * @param loginrName
	 * @return
	 */
	@RequestMapping(value = "/import", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> importPost(HttpServletRequest request) {
		Map<String, Object> map = new HashMap<String, Object>();
		String history = request.getParameter("h");
		// 数据库创建完成
		// 创建数据库，先删除数据库重新创建完成
		Connection conn = null;
		Statement stat = null;
		try {
			Class.forName(SPRING_DATASOURCE_DRIVER);
			// 一开始必须填一个已经存在的数据库
			conn = DriverManager.getConnection(SPRING_DATASOURCE_URL, SPRING_DATASOURCE_USERNAME, SPRING_DATASOURCE_PASSWORD);
			stat = conn.createStatement();
			// 创建数据库hello
			// try {
			logger.info("drop database crm");
			stat.executeUpdate("drop database crm");
			stat.executeUpdate("create database crm");
			// }catch (java.sql.SQLException e) {
			// // TODO: handle exception
			// stat.executeUpdate("drop database " + name);
			// logger.info("create database crm" + name);
			// stat.executeUpdate("create database " + name);
			// }
			stat.close();
			conn.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (stat != null) {
				try {
					stat.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

		try {
			Runtime rt = Runtime.getRuntime();
			Process proc = rt.exec("acc.bat " + history + " crm");
			InputStream stdin = proc.getInputStream();
			InputStreamReader isr = new InputStreamReader(stdin);
			BufferedReader br = new BufferedReader(isr);
			String line = null;
			System.out.println("<OUTPUT>");
			while ((line = br.readLine()) != null)
				System.out.println(line);
			System.out.println("</OUTPUT>");
			int exitVal = proc.waitFor();
			System.out.println("Process exitValue: " + exitVal);
			map.put("exitValue", exitVal);
			// int exitVal = proc.exitValue();
			// System.out.println("Process exitValue: " + exitVal);

		} catch (IOException | InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return map;
	}

	/**
	 * 导出当年账套,复制数据库，复制war,修改数据库链接到导出的数据库
	 * 
	 * @param loginrName
	 * @return
	 */
	@RequestMapping(value = "/export", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> exportPost(HttpServletRequest request) {
		Map<String, Object> map = new HashMap<String, Object>();
		List<String> list = new ArrayList<String>();
		String year = request.getParameter("y");
		String name = "crm" + year;
		// 创建数据库，先删除数据库重新创建完成
		Connection conn = null;
		Statement stat = null;
		try {
			Class.forName(SPRING_DATASOURCE_DRIVER);
			// 一开始必须填一个已经存在的数据库
			conn = DriverManager.getConnection(SPRING_DATASOURCE_URL, SPRING_DATASOURCE_USERNAME, SPRING_DATASOURCE_PASSWORD);
			stat = conn.createStatement();
			// 创建数据库hello
			try {
				logger.info("drop database " + name);
				stat.executeUpdate("create database " + name);
			} catch (java.sql.SQLException e) {
				// TODO: handle exception
				logger.info("drop database " + name);
				stat.executeUpdate("drop database " + name);
				logger.info("create database " + name);
				stat.executeUpdate("create database " + name);
			}
			stat.close();
			conn.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (stat != null) {
				try {
					stat.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		// 数据库创建完成
		try {

			Runtime rt = Runtime.getRuntime();
			Process proc = rt.exec("acc.bat crm " + name);
			InputStream stdin = proc.getInputStream();
			InputStreamReader isr = new InputStreamReader(stdin);
			BufferedReader br = new BufferedReader(isr);
			String line = null;
			logger.info("<OUTPUT>");
			while ((line = br.readLine()) != null) {
				logger.info(line);
			}
			logger.info("</OUTPUT>");
			int exitVal = proc.waitFor();
			logger.info("Process exitValue: " + exitVal);
			map.put("exitValue", exitVal);
			// int exitVal = proc.exitValue();
			// System.out.println("Process exitValue: " + exitVal);

		} catch (IOException | InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// 修改配置文件

		File f = new File("");
		String a_path = f.getAbsolutePath();
		int a_end = a_path.lastIndexOf("\\");
		if (a_end != -1) {
			String a_t = a_path.substring(0, a_end);
			String a_f = a_t + "\\webapps\\" + name + "\\" + "WEB-INF\\classes\\application.properties";
			logger.info(a_f);
			String oldStr = "jdbc:mysql://127.0.0.1:3306/crm?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false";
			String newStr = "jdbc:mysql://127.0.0.1:3306/" + name + "?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false";
			autoReplace(a_f, oldStr, newStr);
			logger.info("autoReplace");
			// try {
			// InputStream in = null;
			// Properties props = new Properties();
			// in = new BufferedInputStream(new FileInputStream(a_f));
			// props.load(new InputStreamReader(in,"utf-8"));
			// OutputStream fos = new FileOutputStream(a_f);
			// props.setProperty("spring.datasource.url",
			// "jdbc:mysql://127.0.0.1:3306/"+name+"?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false");
			// props.store(fos, "Update value");
			// logger.info("Update value");
			// fos.close();
			// in.close();
			// } catch (IOException e) {
			// e.printStackTrace();
			// System.err.println("属性文件更新错误");
			// }
		}

		return map;
	}

	/**
	 * 文件内容替换
	 * 
	 * @param filePath
	 * @param oldstr
	 * @param newStr
	 */
	private static void autoReplace(String filePath, String oldstr, String newStr) {
		File file = new File(filePath);
		Long fileLength = file.length();
		byte[] fileContext = new byte[fileLength.intValue()];
		FileInputStream in = null;
		PrintWriter out = null;
		try {
			in = new FileInputStream(filePath);
			in.read(fileContext);
			// 避免出现中文乱码
			String str = new String(fileContext, "utf-8");
			str = str.replace(oldstr, newStr);
			out = new PrintWriter(filePath);
			out.write(str);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				out.flush();
				out.close();
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	/**
	 * 登录管理员页
	 * 
	 * @param loginrName
	 * @return
	 */
	@RequestMapping(value = "/manager", method = RequestMethod.GET)
	public ModelAndView managerGet() {
		return new ModelAndView("manager/manager");
	}

	/**
	 * 管理员查询
	 * 
	 * @param name
	 * @param page
	 * @return
	 */
	@RequestMapping(value = "/manager", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> marriageName(String name, int page) {
		logger.debug("name:{},page:{}", name, page);
		Map<String, Object> map = new HashMap<String, Object>();
		List<User> list = new ArrayList<User>();
		if (StringUtils.isBlank(name)) {
			list = userService.selectAll((page - 1) * 20, 20);
			// List<User> ulist = new ArrayList<User>();
			List<Map<String, Object>> uList = new ArrayList<Map<String, Object>>();
			for (User user : list) {
				Map<String, Object> detail = new HashMap<String, Object>();
				detail.put("userId", user.getUserId());
				if (user.getUserType() == 0) {
					detail.put("usertype", "超级管理员");
				} else if (user.getUserType() == 1) {
					detail.put("usertype", "管理员");
				} else if (user.getUserType() == 2) {
					detail.put("usertype", "查询员");
				}
				detail.put("username", user.getUsername());
				detail.put("realname", user.getRealname());
				detail.put("userStatus", user.getUserStatus());
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
				detail.put("updateTime", sdf.format(user.getUpdateTime()));
				uList.add(detail);
			}
			int totle = userService.selectCount();
			int u = totle % 20;
			logger.debug("totlepage:{}", u);
			int pageCount = 1;
			if (u > 0) {
				pageCount = totle / 20 + 1;
			}
			map.put(Constants.LIST, uList);
			map.put(Constants.TOTLE, totle);
			map.put(Constants.TOTLE_PAGE, pageCount);
			return map;
		} else {
			User user = userService.selectByName(name);
			if (user != null) {
				List<Map<String, Object>> ulist = new ArrayList<Map<String, Object>>();
				Map<String, Object> detail = new HashMap<String, Object>();
				detail.put("userId", user.getUserId());
				if (user.getUserType() == 0) {
					detail.put("usertype", "超级管理员");
				} else {
					detail.put("usertype", "管理员");
				}
				detail.put("username", user.getUsername());
				detail.put("realname", user.getRealname());
				detail.put("userStatus", user.getUserStatus());
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				detail.put("updateTime", sdf.format(user.getUpdateTime()));
				ulist.add(detail);
				map.put(Constants.LIST, ulist);
				map.put(Constants.TOTLE, 1);
				map.put(Constants.TOTLE_PAGE, 1);
			}
		}
		return map;

	}

	/**
	 * 工作者工作信息
	 * 
	 * @param userId
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/workerDetail", method = RequestMethod.GET)
	public ModelAndView workerDetailGET(int userId, HttpServletRequest request) {
		Map<String, Object> model = new HashMap<>();
		try {
			String username = new String(request.getParameter("username").getBytes("iso-8859-1"), "utf-8");
			model.clear();
			model.put(Constants.USER_ID, userId);
			model.put(Constants.CHOOSEUSERNAME, username);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return new ModelAndView("manager/workerDetail", Constants.MODEL, model);

	}

	/**
	 * 用户的状态更改
	 * 
	 * @param userId
	 * @param userStatus
	 * @return
	 */
	@RequestMapping(value = "/userStatus", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> userStatus(int userId, boolean userStatus) {
		logger.info("userId:{},userStatus:{}", userId, userStatus);
		Map<String, Object> map = new HashMap<>();
		User user = userService.selectByPrimaryKey(userId);
		if (user != null) {
			user.setUserStatus(userStatus);
			userService.updateByPrimaryKeySelective(user);
			map.put(Constants.MESSAGE, MSG_UPDATE_SUCCESS);
			return map;
		}
		map.put(Constants.MESSAGE, MSG_UPDATE_ERROR);
		return map;
	}

	/**
	 * 跳转新增用户页
	 * 
	 * @return
	 */
	@RequestMapping(value = "/addUser", method = RequestMethod.GET)
	public ModelAndView addUserGet() {
		return new ModelAndView("manager/user_add");
	}

	/**
	 * 添加用户
	 * 
	 * @param username
	 * @param password
	 * @param userType
	 * @param realname
	 * @param redirectAttributes
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/addUser", method = RequestMethod.POST)
	public ModelAndView addUserPost(String username, String password, Integer userType, String realname, RedirectAttributes redirectAttributes, HttpSession session) {
		logger.debug("username:{},password:{},realname{},userType{}", username, password, realname, userType);
		if (StringUtils.isBlank(username)) {
			redirectAttributes.addFlashAttribute(Constants.MESSAGE, MSG_USER_NOT_EMPTY);
			return new ModelAndView(Constants.REDIRECT + Constants.COLON + Constants.ADD_USER);
		}
		if (StringUtils.isBlank(password)) {
			redirectAttributes.addFlashAttribute(Constants.MESSAGE, MSG_PASSWORD_NOT_EMPTY);
			return new ModelAndView(Constants.REDIRECT + Constants.COLON + Constants.ADD_USER);
		}
		User user = userService.selectByName(username);
		if (user != null) {
			redirectAttributes.addFlashAttribute(Constants.USER_NAME, username);
			redirectAttributes.addFlashAttribute(Constants.USER_PASSWORD, password);
			redirectAttributes.addFlashAttribute(Constants.MESSAGE, MSG_USER_EXIST);
		}
		User record = new User();
		record.setUsername(username);
		UsernameAndPasswordMd5 md5 = new UsernameAndPasswordMd5();
		String md5Password = md5.getMd5(username, password);
		record.setPassword(md5Password);
		record.setRealname(realname);
		record.setUserStatus(true);
		record.setUserType(userType);
		record.setCreateTime(new Date());
		record.setUpdateTime(new Date());
		userService.insert(record);
		return new ModelAndView(Constants.REDIRECT + Constants.COLON + Constants.MANAGER);
	}

	/**
	 * 刪除用戶
	 * 
	 * @param userId
	 * @param redirectAttributes
	 * @param session
	 * @return
	 */
	@RequestMapping(value = "/deleteUser", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> addUserPost(Integer userId, RedirectAttributes redirectAttributes, HttpSession session) {
		logger.debug("userId:{}", userId);
		Map<String, Object> map = new HashMap<String, Object>();
		int u = userService.deleteByPrimaryKey(userId);
		if (u > 0) {
			map.put(Constants.MESSAGE, "删除成功");
		} else {
			map.put(Constants.MESSAGE, "删除失败");
		}
		return map;
	}

	/**
	 * 检查用户名是否重复
	 * 
	 * @param userName
	 * @return
	 */
	@RequestMapping(value = "/checkUserName", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> checkUserName(HttpServletRequest request) {
		String userName = request.getParameter("username");
		logger.debug("username:{}", userName);
		Map<String, Object> map = new HashMap<String, Object>();
		User use = userService.selectByName(userName);
		if (use != null) {
			map.put("status", true);
			map.put(Constants.MESSAGE, MSG_USER_EXIST);
		} else {
			map.put("status", false);
			map.put(Constants.MESSAGE, MSG_USERNAME_DO);
		}
		return map;
	}

	/**
	 * 检查此用户的原密码是否正确
	 * 
	 * @param userName
	 * @return
	 */
	@RequestMapping(value = "/changePwd", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> changePwd(String password, Integer userId, HttpSession session) {
		Map<String, Object> map = new HashMap<String, Object>();
		User user = userService.selectByPrimaryKey(userId);
		UsernameAndPasswordMd5 md5 = new UsernameAndPasswordMd5();
		String md5Password = md5.getMd5(user.getUsername(), password);
		user.setPassword(md5Password);
		userService.updateByPrimaryKeySelective(user);
		map.put(Constants.MESSAGE, "密码修改成功！");
		return map;
	}

}
